package com.GPS_based_training.support;

import java.util.ArrayList;

/**
 * @author Danilo Dessi'
 * This class is used to describe the training session 
 */
public class Training {
	
	private final double MULTIPLIER_FOR_KILOMETERS_HOURS = 3.6; // A multiplier to convert m/s in km/h
	private final double DIVISOR_FROM_HOURS_TO_MINUTE = 60;
	
	//The name that the user choice to save training
	private String name;
	
	//The date of the training
	private String date;
	
	//detections describes the training session
	private ArrayList<TrainingElement> detections;

	//index of first detections to compute statistics on last x meters
	private int posDetectionXMeters;
	
	
	public Training(){
		
		detections = new ArrayList<TrainingElement>();
		name = "";
		date = "";
		posDetectionXMeters = 0;
		
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * Insert new detection in the training
	 * @param trainingElement
	 */
	public void add(TrainingElement trainingElement) {
		
		detections.add(trainingElement);
		
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * Getter of the detections taken by the GPS
	 * @return the ArrayList containing training elements
	 */
	public ArrayList<TrainingElement> getDetections() {
		return detections;
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * Retrieving of the last detection
	 * @return The last detection
	 */
	public TrainingElement lastDetection() {
		
		int size = detections.size();
		TrainingElement temp = null;
		
		if( size > 0) {
			temp = detections.get(size - 1);
		}
		
		return  temp;
		
	}
	
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This function computes the total distance of the training
	 * @return The total distance
	 */
	public double totalDistance() {
		
		int size = detections.size();
		
		//Declaration of variable that will contain the sum
		double distance = 0;
		 
		if(size > 0) {
			
			distance = detections.get(size - 1).getDistance();
			
		}
			
		return distance;
	}
	
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This function computes the total time of the training
	 * @return The total time of the training
	 */
	public double totalTime() {
		int size = detections.size();
		double time = 0;
		
		if( size > 0) {
			
			time = detections.get(size - 1).getTime();
			
		}
		
		return time ;
		
	}
	
	
	/**
	 * This function computes the mean speed of the training
	 * @return The mean speed
	 */
	public double meanSpeed() {
		
		double meanSpeed = 0;
		double totalTime = totalTime();	
		
		if (totalTime > 0) {
			 
			meanSpeed = totalDistance() / totalTime;
			
		}
		
		return meanSpeed * MULTIPLIER_FOR_KILOMETERS_HOURS;
		
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This function computes the mean pace of the training
	 * @return The mean pace
	 */
	public double meanPace() {
		
		double meanPace = 0;
		double meanSpeed = meanSpeed();
		
		if (meanSpeed > 0) {
			//the pace is computed as the reverse of the speed 
			meanPace = 1 / ( meanSpeed / DIVISOR_FROM_HOURS_TO_MINUTE );
			
		}
		
		return meanPace;
		
	}
	
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This function computes the mean speed in last x meters of the training
	 * @param xMeters The meters on which we compute the mean speed
	 * @return The mean speed of last x meters
	 */
	public double meanSpeedXMeters(double xMeters) {
		
		double totalDistance = totalDistance();
		double distance = 0;
		double time = 0;
		double meanSpeedXMeters = 0;
		
		if ( totalDistance > xMeters ) {
			
			distance = totalDistance - detections.get(posDetectionXMeters).getDistance();
			
			//if distance is greater of the last x meters, we shift the detections
			while ( distance > xMeters ) {
				
				posDetectionXMeters++;
				distance = totalDistance - detections.get(posDetectionXMeters).getDistance();
				
			} 
			
			//we retrieve the time of the detections
			time = totalTime() - detections.get(posDetectionXMeters).getTime();
				
			if (time > 0) {
				//we compute the mean speed
				meanSpeedXMeters = distance / time;
			}
			
		}
		
		return meanSpeedXMeters * MULTIPLIER_FOR_KILOMETERS_HOURS;		
		
	}
	
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This function computes the pace in last x meters of the training
	 * @param xMeters The meters on which we compute the pace speed
	 * @return The pace of last x meters
	 */
	public double meanPaceXMeters(double xMeters) {
		
		double meanPaceXMeters = 0;
		double meanSpeedXMeters = meanSpeedXMeters(xMeters);
		
		if( meanSpeedXMeters > 0 ) {
			
			meanPaceXMeters = 1 / (meanSpeedXMeters / DIVISOR_FROM_HOURS_TO_MINUTE);
			
		}
		
		return meanPaceXMeters;
		
	}
	
	/**
	 * @author Danilo Dessi'
	 * 
	 * This function is used to verify if the training is empty
	 * @return if the training is empty returns true, false otherwise
	 */
	public boolean isEmpty() {
		
		return detections.isEmpty();
		
	}

	/**
	 * @author Danilo Dessi'
	 * 
	 * This method return the name of the training
	 * @return the name of the training
	 */
	public String getName() {
		return name;
	}

	/**
	 * @author Danilo Dessi'
	 * 
	 * This method permit to rename the training
	 * @param name The new name of the training
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @author Danilo Dessi'
	 * 
	 * This method return the date of the training
	 * @return The date of the training
	 */
	public String getDate() {
		return date;
	}

	/**
	 * @author Danilo Dessi'
	 * 
	 * This method permit to set up the date of the training
	 * @param date The date of the training
	 */
	public void setDate(String date) {
		this.date = date;
	}
	
	
}
